﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Validation;
using System.Xml.Linq;
using mvcForum.Core;
using System.ComponentModel.DataAnnotations.Schema;

namespace mvcForum.DataProvider.EntityFramework {

	public class MVCForumContext : DbContext {

		public MVCForumContext() : base("DefaultConnection") { }
		public MVCForumContext(String nameOrConnectionString) : base(nameOrConnectionString) { }

		//public DbSet<User> Users { get; set; }
		//public DbSet<Role> Roles { get; set; }
		public DbSet<AccessMask> AccessMasks { get; set; }
		public DbSet<Board> Boards { get; set; }
		public DbSet<Category> Categories { get; set; }
		public DbSet<Forum> Forums { get; set; }
		public DbSet<Topic> Topics { get; set; }
		public DbSet<Post> Posts { get; set; }
		public DbSet<ForumUser> ForumUsers { get; set; }
		public DbSet<GroupMember> GroupMembers { get; set; }
		public DbSet<Group> Groups { get; set; }
		public DbSet<Attachment> Attachments { get; set; }
		public DbSet<ForumAccess> ForumAccesses { get; set; }
		public DbSet<ForumSettings> ForumSettings { get; set; }
		public DbSet<ForumTrack> ForumTracks { get; set; }
		public DbSet<TopicTrack> TopicTracks { get; set; }
		public DbSet<PostReport> PostReports { get; set; }
		public DbSet<BannedIP> BannedIPs { get; set; }
		public DbSet<FollowTopic> FollowTopics { get; set; }
		public DbSet<FollowForum> FollowForums { get; set; }
		public DbSet<AddOnConfiguration> AddOnConfigurations { get; set; }

		/// <summary>
		/// If you inherit from this class and override this method, please remember to call it on base.
		/// </summary>
		/// <param name="modelBuilder"></param>
		protected override void OnModelCreating(DbModelBuilder modelBuilder) {
			base.OnModelCreating(modelBuilder);

			// We don't want pluralized table names!
			modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
			// No default cascaded deleted on one-to-many!
			modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

			// Let's map the "enum fix" fields to something nice!
			modelBuilder.Entity<AccessMask>().Ignore(p => p.AccessFlag);
			modelBuilder.Entity<AccessMask>().Property(p => p.AccessFlagValue).HasColumnName("AccessFlag");
			modelBuilder.Entity<ForumUser>().Ignore(p => p.UserFlag);
			modelBuilder.Entity<ForumUser>().Property(p => p.UserFlagValue).HasColumnName("UserFlag");
			modelBuilder.Entity<Post>().Ignore(p => p.Flag);
			modelBuilder.Entity<Post>().Property(p => p.FlagValue).HasColumnName("Flag");
			modelBuilder.Entity<Topic>().Ignore(p => p.Flag);
			modelBuilder.Entity<Topic>().Property(p => p.FlagValue).HasColumnName("Flag");
			modelBuilder.Entity<Topic>().Ignore(p => p.Type);
			modelBuilder.Entity<Topic>().Property(p => p.TypeValue).HasColumnName("Type");

			// A board can have many categories
			modelBuilder.Entity<Board>().HasMany(x => x.Categories).WithRequired(i => i.Board);
			// A category can have many boards
			modelBuilder.Entity<Category>().HasMany(x => x.Forums).WithRequired(i => i.Category);
			// A forum can have many topics!
			modelBuilder.Entity<Forum>().HasMany(x => x.Topics).WithRequired(i => i.Forum);
			modelBuilder.Entity<Forum>().HasOptional(x => x.LastPost);
			modelBuilder.Entity<Forum>().HasOptional(x => x.LastTopic);
			modelBuilder.Entity<Forum>().HasOptional(x => x.LastPostUser);
			// A topic can have many posts.
			modelBuilder.Entity<Topic>().HasMany(x => x.Posts).WithRequired(i => i.Topic);
			modelBuilder.Entity<Topic>().HasOptional(x => x.LastPost);
			modelBuilder.Entity<Topic>().HasOptional(x => x.LastPostAuthor);
			// A topic can have many attachments.
			modelBuilder.Entity<Post>().HasMany(x => x.Attachments).WithRequired(i => i.Post);

			modelBuilder.Entity<Topic>().HasMany(x => x.Followers).WithRequired(i => i.Topic);
			modelBuilder.Entity<Forum>().HasMany(x => x.Followers).WithRequired(i => i.Forum);

			//modelBuilder.Entity<Profile>().HasMany(x => x.Settings).WithRequired(i => i.Profile);

			// Do not map the CustomData property to the database!
			modelBuilder.Entity<Topic>().Ignore(t => t.CustomData);
			// Do not map the CustomData property to the database!
			modelBuilder.Entity<Post>().Ignore(p => p.CustomData);
		}
	}
}